from django.shortcuts import render

# Create your views here.
from django.http import JsonResponse
from rest_framework.views import APIView
from allmodels.models import SysMenu  # 假设菜单模型在 allmodels 中
from django.db import transaction
import json
from login.views import verify_token  # 假设已经有验证 token 的函数
from django.db.models import Q

class UpdateMenuView(APIView):
    def put(self, request, id, *args, **kwargs):
        # 获取 Authorization 令牌并验证
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        # 枚举值映射
        type_enum = {
            "MENU": 1,
            "CATALOG": 2,
            "EXTLINK": 3,
            "BUTTON": 4,
            "NULL": None
        }
        reverse_type_enum = {v: k for k, v in type_enum.items()}  # 反向映射用于返回时

        try:
            # 获取请求中的 JSON 数据
            data = json.loads(request.body)

            # 查找菜单，如果不存在则返回错误
            menu = SysMenu.objects.get(id=id)

            # 更新菜单的字段
            menu.parent_id = data.get('parentId', menu.parent_id)
            menu.name = data.get('name', menu.name)

            # 处理 type 字段，转换传入的枚举值为数字
            type_value = data.get('type', reverse_type_enum[menu.type])
            if type_value in type_enum:
                menu.type = type_enum[type_value]
            else:
                return JsonResponse({
                    'code': '10009',
                    'msg': '无效的菜单类型'
                }, status=400)

            menu.route_name = data.get('routeName', menu.route_name)
            menu.route_path = data.get('routePath', menu.route_path)
            menu.component = data.get('component', menu.component)
            menu.perm = data.get('perm', menu.perm)
            menu.visible = data.get('visible', menu.visible)
            menu.sort = data.get('sort', menu.sort)
            menu.icon = data.get('icon', menu.icon)
            menu.redirect = data.get('redirect', menu.redirect)
            menu.keep_alive = data.get('keepAlive', menu.keep_alive)
            menu.always_show = data.get('alwaysShow', menu.always_show)

            # 处理 params 参数
            params = data.get('params', [])
            menu.params = json.dumps(params)  # 假设 params 存储为 JSON 字符串

            # 保存更新
            with transaction.atomic():
                menu.save()

            return JsonResponse({
                'code': '00000',
                'data': {
                    'id': menu.id,
                    'parentId': menu.parent_id,
                    'name': menu.name,
                    'type': reverse_type_enum.get(menu.type, "NULL"),  # 返回时转换为枚举值
                    'routeName': menu.route_name,
                    'routePath': menu.route_path,
                    'component': menu.component,
                    'perm': menu.perm,
                    'visible': menu.visible,
                    'sort': menu.sort,
                    'icon': menu.icon,
                    'redirect': menu.redirect,
                    'keepAlive': menu.keep_alive,
                    'alwaysShow': menu.always_show,
                    'params': json.loads(menu.params) if menu.params else []
                },
                'msg': '菜单更新成功'
            })

        except SysMenu.DoesNotExist:
            return JsonResponse({
                'code': '10006',
                'msg': '菜单不存在'
            }, status=404)

        except json.JSONDecodeError:
            return JsonResponse({
                'code': '10007',
                'msg': '请求体格式错误'
            }, status=400)

        except Exception as e:
            return JsonResponse({
                'code': '10008',
                'msg': f'未知错误: {str(e)}'
            }, status=500)

class DeleteMenuView(APIView):
    def delete(self, request, id, *args, **kwargs):
        # 获取 Authorization 令牌并验证
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        try:
            # 分割多个ID的情况
            ids = [int(i) for i in id.split(',')]

            with transaction.atomic():
                # 批量删除菜单
                SysMenu.objects.filter(id__in=ids).delete()

            return JsonResponse({
                'code': '00000',
                'data': {},
                'msg': '菜单删除成功'
            })

        except Exception as e:
            return JsonResponse({
                'code': '10006',
                'msg': f'删除失败: {str(e)}'
            }, status=500)

class MenuListView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取 Authorization 令牌并验证
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        # 获取查询参数
        keywords = request.GET.get('keywords', '')
        status = request.GET.get('status', '')

        # 构建查询条件
        filters = Q()
        if keywords:
            filters &= Q(name__icontains=keywords)
        if status:
            filters &= Q(visible=status)

        # 查询父菜单（parent_id 为 0 的菜单为顶层菜单）
        top_level_menus = SysMenu.objects.filter(parent_id=0).filter(filters).order_by('sort')

        # 递归获取菜单及其子菜单
        def get_children(menu):
            # 查找子菜单
            children = SysMenu.objects.filter(parent_id=menu.id).order_by('sort')
            # 如果visible为true返回1反之0
            return [
                {
                    "id": child.id,
                    "parentId": child.parent_id,
                    "name": child.name,
                    "type": child.type,
                    "routeName": child.route_name,
                    "routePath": child.route_path,
                    "component": child.component,
                    "sort": child.sort,
                    "visible": 1 if child.visible else 0,  # 如果visible为true返回1反之0
                    "icon": child.icon,
                    "redirect": child.redirect,
                    "perm": child.perm,
                    "children": get_children(child)  # 递归调用
                }
                for child in children
            ]

        # 构建返回的数据结构
        menu_list = []
        for menu in top_level_menus:
            # 如果visible为true返回1反之0
            menu.visible = 1 if menu.visible else 0
            menu_list.append({
                "id": menu.id,
                "parentId": menu.parent_id,
                "name": menu.name,
                "type": menu.type,
                "routeName": menu.route_name,
                "routePath": menu.route_path,
                "component": menu.component,
                "sort": menu.sort,
                "visible": menu.visible,
                "icon": menu.icon,
                "redirect": menu.redirect,
                "perm": menu.perm,
                "children": get_children(menu)  # 获取子菜单
            })

        # 返回数据
        return JsonResponse({
            "code": "00000",
            "data": menu_list,
            "msg": "一切ok"
        })

class CreateMenuView(APIView):
    def post(self, request, *args, **kwargs):
        # 获取 Authorization 令牌并验证
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        try:
            # 解析请求体
            data = json.loads(request.body)

            # 验证必填参数
            if 'name' not in data or 'type' not in data:
                return JsonResponse({
                    'code': '10006',
                    'msg': '菜单名称和类型为必填项'
                }, status=400)

            # 开始保存菜单
            with transaction.atomic():
                menu = SysMenu(
                    parent_id=data.get('parentId', 0),  # 父菜单ID默认为0（顶层菜单）
                    name=data['name'],
                    type=data['type'],
                    route_name=data.get('routeName', ''),
                    route_path=data.get('routePath', ''),
                    component=data.get('component', ''),
                    perm=data.get('perm', ''),
                    visible=data.get('visible', 1),  # 显示状态默认为显示
                    sort=data.get('sort', 0),  # 排序默认为0
                    icon=data.get('icon', ''),
                    redirect=data.get('redirect', ''),
                    keep_alive=data.get('keepAlive', 0),
                    always_show=data.get('alwaysShow', 0)
                )
                menu.save()

            return JsonResponse({
                'code': '00000',
                'msg': '菜单创建成功',
                'data': {
                    'id': menu.id,
                    'parentId': menu.parent_id,
                    'name': menu.name,
                    'type': menu.type,
                    'routeName': menu.route_name,
                    'routePath': menu.route_path,
                    'component': menu.component,
                    'perm': menu.perm,
                    'visible': menu.visible,
                    'sort': menu.sort,
                    'icon': menu.icon,
                    'redirect': menu.redirect,
                    'keepAlive': menu.keep_alive,
                    'alwaysShow': menu.always_show
                }
            })

        except json.JSONDecodeError:
            return JsonResponse({
                'code': '10007',
                'msg': '请求体格式错误'
            }, status=400)

        except Exception as e:
            return JsonResponse({
                'code': '10008',
                'msg': f'未知错误: {str(e)}'
            }, status=500)

class UpdateMenuVisibleView(APIView):
    def patch(self, request, menuId, *args, **kwargs):
        # 获取 Authorization 令牌并验证
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        # 获取查询参数中的 visible 值
        visible = request.GET.get('visible')
        if visible is None:
            return JsonResponse({
                'code': '10006',
                'msg': 'visible 参数为必填项'
            }, status=400)

        try:
            visible = int(visible)  # 转换为整数，确保是 1 或 0
        except ValueError:
            return JsonResponse({
                'code': '10007',
                'msg': 'visible 参数必须是整数'
            }, status=400)

        if visible not in [0, 1]:
            return JsonResponse({
                'code': '10008',
                'msg': 'visible 参数必须是 0 或 1'
            }, status=400)

        try:
            # 更新菜单的 visible 状态
            with transaction.atomic():
                menu = SysMenu.objects.get(id=menuId)
                menu.visible = visible
                menu.save()

            return JsonResponse({
                'code': '00000',
                'data': {},
                'msg': '菜单显示状态更新成功'
            })

        except SysMenu.DoesNotExist:
            return JsonResponse({
                'code': '10009',
                'msg': '菜单不存在'
            }, status=404)

        except Exception as e:
            return JsonResponse({
                'code': '10010',
                'msg': f'未知错误: {str(e)}'
            }, status=500)

class GetMenuFormView(APIView):
    def get(self, request, id, *args, **kwargs):
        # 获取 Authorization 令牌并验证
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        try:
            # 获取菜单表单数据
            menu = SysMenu.objects.get(id=id)
            # type：1-菜单 2-目录 3-外链 4-按钮
            if menu.type == 1:
                menu.type = 1
            elif menu.type == 2:
                menu.type = 'CATALOG'
            elif menu.type == 3:
                menu.type = 'EXTLINK'
            elif menu.type == 4:
                menu.type = 'BUTTON'


            # 构建返回的数据结构
            menu_data = {
                "id": menu.id,
                "parentId": menu.parent_id,
                "name": menu.name,
                "type": menu.type,  # 菜单类型
                "routeName": menu.route_name,
                "routePath": menu.route_path,
                "component": menu.component,
                "perm": menu.perm,
                "visible": menu.visible,
                "sort": menu.sort,
                "icon": menu.icon,
                "redirect": menu.redirect,
                "keepAlive": menu.keep_alive,
                "alwaysShow": menu.always_show,
                "params": None  # 可根据实际需求返回 params 数据
            }

            # 返回成功响应
            return JsonResponse({
                'code': '00000',
                'data': menu_data,
                'msg': '菜单表单数据获取成功'
            })

        except SysMenu.DoesNotExist:
            return JsonResponse({
                'code': '10006',
                'msg': '菜单不存在'
            }, status=404)

        except Exception as e:
            return JsonResponse({
                'code': '10007',
                'msg': f'未知错误: {str(e)}'
            }, status=500)

class MenuRoutesView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取 Authorization 令牌
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        try:
            # 获取所有菜单数据
            menus = SysMenu.objects.filter(visible=1).order_by('sort')

            # 递归生成菜单树
            def build_menu_tree(menu_list, parent_id):
                tree = []
                for menu in menu_list:
                    if menu.parent_id == parent_id:
                        # 构建菜单项
                        menu_data = {
                            "path": menu.route_path,
                            "component": menu.component,
                            "redirect": menu.redirect,
                            "name": menu.route_name,
                            "meta": {
                                "title": menu.name,
                                "icon": menu.icon,
                                "hidden": not bool(menu.visible),
                                "alwaysShow": bool(menu.always_show),
                                "params": {}  # 可以根据需要处理参数
                            },
                            "children": build_menu_tree(menu_list, menu.id)  # 递归查找子菜单
                        }
                        tree.append(menu_data)
                return tree

            # 构建菜单树
            menu_tree = build_menu_tree(menus, parent_id=0)

            # 返回成功响应
            return JsonResponse({
                'code': '00000',
                'data': menu_tree,
                'msg': '操作成功'
            })

        except Exception as e:
            return JsonResponse({
                'code': '10008',
                'msg': f'未知错误: {str(e)}'
            }, status=500)


class MenuDetailView(APIView):
    def get(self, request, id, *args, **kwargs):
        # 获取 Authorization 令牌
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        try:
            # 根据菜单 ID 获取菜单详情
            menu = SysMenu.objects.get(id=id)

            # 返回菜单详情
            return JsonResponse({
                'code': '00000',
                'data': {
                    "id": menu.id,
                    "parentId": menu.parent_id,
                    "name": menu.name,
                    "type": menu.type,
                    "routeName": menu.route_name,
                    "routePath": menu.route_path,
                    "component": menu.component,
                    "perm": menu.perm,
                    "visible": menu.visible,
                    "sort": menu.sort,
                    "icon": menu.icon,
                    "redirect": menu.redirect,
                    "keepAlive": menu.keep_alive,
                    "alwaysShow": menu.always_show,
                    "params": menu.params
                },
                'msg': '菜单详情获取成功'
            })

        except SysMenu.DoesNotExist:
            return JsonResponse({
                'code': '10006',
                'msg': '菜单不存在'
            }, status=404)

        except Exception as e:
            return JsonResponse({
                'code': '10008',
                'msg': f'未知错误: {str(e)}'
            }, status=500)

class MenuOptionsView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取 Authorization 令牌
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': '10004',
                'msg': '无效的令牌'
            }, status=401)

        access_token = auth_header.split(' ')[1]  # 获取实际的 JWT 令牌

        # 验证令牌有效性
        payload = verify_token(access_token)
        if 'error' in payload:
            return JsonResponse({
                'code': '10005',
                'msg': '令牌验证失败'
            }, status=401)

        # 获取查询参数
        only_parent = request.GET.get('onlyParent', 'false').lower() == 'true'

        # 查询菜单列表
        if only_parent:
            menus = SysMenu.objects.filter(parent_id=0).order_by('sort')  # 仅父级菜单
        else:
            menus = SysMenu.objects.all().order_by('sort')

        # 递归生成菜单树
        def build_menu_tree(menu_list, parent_id=0):
            menu_tree = []
            for menu in menu_list:
                if menu.parent_id == parent_id:
                    children = build_menu_tree(menu_list, menu.id)
                    menu_tree.append({
                        "value": menu.id,
                        "label": menu.name,
                        "children": children if children else None
                    })
            return menu_tree

        # 构建菜单树
        menu_tree = build_menu_tree(menus)

        # 返回菜单选项列表
        return JsonResponse({
            "code": "00000",
            "data": menu_tree,
            "msg": "操作成功"
        })